package com.hyg.lib_base.Net;

/**
 * Created by panfu on 2017/12/20.
 */

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.hyg.lib_base.mainUtils.Utils;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.security.cert.CertificateException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class NetworkOP {
    public JSONObject jsobj;
    public Handler handler;
    public String tag;
    public String net_addr;
    public String data;
    public FormBody forms;
    public File files;

    public NetworkOP(String tag, String string, Handler handler, String net_addr) {
        this.forms = forms;
        this.handler = handler;
        this.tag = tag;
        this.net_addr = net_addr;
    }

    public NetworkOP(String tag, FormBody forms, Handler handler, String net_addr) {
        this.forms = forms;
        this.handler = handler;
        this.tag = tag;
        this.net_addr = net_addr;
    }


    public NetworkOP(String tag, FormBody forms, File data, Handler handler, String net_addr) {
        this.forms = forms;
        this.files = data;
        this.handler = handler;
        this.tag = tag;
        this.net_addr = net_addr;
    }

    public X509TrustManager setSSL() {
        //定义一个信任所有证书的TrustManager 兼容5.0系统以下可以使用https连接
        final X509TrustManager trustAllCert = new X509TrustManager() {
            @Override
            public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
            }

            @Override
            // 如果使用自定义X509TrustManager实现类，必须在checkServerTrusted() 方法中校验服务端证书的合法性，否则可能受到中间人攻击
            public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                HostnameVerifier hnv = new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        if (net_addr.equals(hostname)) {
                            return true;
                        } else {
                            HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
                            return hv.verify(hostname, session);
                        }
                    }
                };
            }

            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return new java.security.cert.X509Certificate[]{};
            }
        };

        return trustAllCert;
    }

    public void sethttpCall(OkHttpClient okHttpClient, Request request) {
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
//                Log.d("okhttpCallback", ""+e.getMessage());
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("code", "404");
                    jsonObject.put("message", "请求服务器失败,请检查网络是否正常连通");
                    jsonObject.put("data", "");
                    Message msg = new Message();
                    msg.what = Integer.parseInt(tag);
                    msg.obj = jsonObject;
                    handler.sendMessage(msg);
                    Log.d("PostData---Failure", msg.what + "、" + msg.obj);
                } catch (JSONException es) {
                    es.printStackTrace();
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //此方法运行在子线程中，不能在此方法中进行UI操作。
                String result = response.body().string();
                if (response.isSuccessful()) {
                    try {
                        JSONObject jsonObject = new JSONObject(result);
                        Message msg = new Message();
                        msg.what = Integer.parseInt(tag);
                        msg.obj = jsonObject;
                        handler.sendMessage(msg);
                        Log.d("PostData---Success", msg.what + "、" + msg.obj);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                } else {
                    try {
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("code", "404");
                        jsonObject.put("message", "连接服务器超时，请稍后重试");
                        jsonObject.put("data", "");
                        Message msg = new Message();
                        msg.what = Integer.parseInt(tag);
                        msg.obj = jsonObject;
                        handler.sendMessage(msg);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
                response.body().close();
            }
        });
    }

    public void okhttpAsyncPost() {
        OkHttpClient okHttpClient = new OkHttpClient.Builder().
                sslSocketFactory(new SSLSocketFactoryCompat(setSSL()), setSSL()).
                build();
        //Form表单格式的参数传递
        Request request = new Request
                .Builder()
                .post(forms)//Post请求的参数传递
                .url(net_addr)
                .build();
        sethttpCall(okHttpClient, request);
    }

    public void okhttpAsyncGet() {
        OkHttpClient okHttpClient = new OkHttpClient.Builder().
                sslSocketFactory(new SSLSocketFactoryCompat(setSSL()), setSSL()).build();
        Request request = new Request
                .Builder()
                .url(net_addr + "?" + data)
                .build();

        sethttpCall(okHttpClient, request);
    }

    public void okhttpAsyncJson() {
        OkHttpClient okHttpClient = new OkHttpClient.Builder().
                sslSocketFactory(new SSLSocketFactoryCompat(setSSL()), setSSL()).build();

        final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, jsobj.toString());
        Request request = new Request.Builder()
                .url(net_addr)
//                .post(forms)
                .post(body)
                .build();
        sethttpCall(okHttpClient, request);
    }

    public void okhttpAsyncFile() {
        OkHttpClient okHttpClient = new OkHttpClient.Builder().
                sslSocketFactory(new SSLSocketFactoryCompat(setSSL()), setSSL()).build();
//        application/octet-stream
//        1、只能提交二进制，而且只能提交一个二进制，如果提交文件的话，只能提交一个文件,后台接收参数只能有一个，而且只能是流（或者字节数组）
        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        builder.addFormDataPart("file", files.getName(), RequestBody.create(MediaType.parse("application/octet-stream"), files));
        if (!Utils.isEmpty(forms)) {
            for (int i = 0; i < forms.size(); i++) {
                builder.addFormDataPart(forms.name(i), forms.value(i));
            }
        }
        MultipartBody multipartBody = builder.build();
        Request request = new Request.Builder()
                .url(net_addr)
                .post(multipartBody)
                .build();
        sethttpCall(okHttpClient, request);
    }

}